﻿; (function () {

    'use strict';

    window.LazyValuesSet = function LazyValuesSet() {
        //   this.arrMask = [0, 0, 0, 0, 0,/* */ 0, 0, 0, 0, 0];
        this.mask = 0 | 0;
        this.count = 0;
        this._values = null;
        // this._values = []; // don't eager instanciate the array (IE11)
        this._areValuesClean = false;
    }

    LazyValuesSet.prototype.add = function (value) {
        var bitValue = 1 << value;
        if (this.mask & bitValue)
            return false;

        this.mask = this.mask | bitValue;
        this.count++;
        this._areValuesClean = false;
        // this._values.insertOrdered(value);
        return true;
    };

    LazyValuesSet.prototype.doAdd = function (value) {

        this.mask = this.mask | 1 << value;
        this.count++;
        this._areValuesClean = false;
        // this._values.insertOrdered(value);
        return true;
    };

    LazyValuesSet.prototype.addRange = function (values) {
        var added = false;
        for (var i = 0, len = values.length; i < len; i++) {
            added |= this.add(values[i]);
        }
        return added;
    };

    LazyValuesSet.prototype.remove = function (value) {
        var bitValue = 1 << value;
        if (!(this.mask & bitValue))
            return false;

        this.mask ^= bitValue;
        this.count--;
        this._areValuesClean = false;
        return true;
    };

    LazyValuesSet.prototype.contains = function (value) {
        return (this.mask & 1 << value);
    };

    LazyValuesSet.prototype.clear = function () {
        this.mask = 0 | 0;
        this.count = 0;
        // this._values = null; // don't eager instanciate the array (IE11)
        this._areValuesClean = false;
    };

    // this is inlinable by compiler FF ( path to values)
    LazyValuesSet.prototype.getValues = function () {
        return this._areValuesClean ? this._values : this._getFreshValues();
    };

    LazyValuesSet.prototype._getFreshValues = function () {
        this._values = this._values ? this._values.clear() : [];
        var mask = this.mask << 1;
        var i = 0;
        while (mask >>= 1) {
            if (this.mask & (1 << i))
                this._values.push(i)

            i++;
        }

        this._areValuesClean = true;
        return this._values;
    };

    LazyValuesSet.prototype.getValues2 = function () {
        if (this._areValuesClean)
            return this._values;


        this._values = this._values ? this._values.clear() : [];
        var mask = this.mask << 1;
        var i = 0;
        while (mask >>= 1) {
            if (this.mask & (1 << i))
                this._values.push(i)

            i++;
        }

        this._areValuesClean = true;
        return this._values;
    };

}(window));